﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using System.Windows.Threading;

namespace Wimat.Collections.Tests
{
    [TestFixture]
    public class LazyCurrentCollectionViewTests
    {
        #region Setup
        private LazyCurrentCollectionView _target;
        private double _delay;
        private double _delayTolerance;
        private DispatcherFrame _frame;
        private int _lazyCurrentCallCount;
        private DateTime _lazyCurrentChanged_Now;

        [SetUp]
        public void SetUp()
        {
            _delay = 100;
            _delayTolerance = 10;
            _lazyCurrentCallCount = 0;
            _frame = new DispatcherFrame();
            var baseList = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            _target = new LazyCurrentCollectionView(baseList);
            _target.LazyCurrentChangedDelay = _delay;
            _target.LazyCurrentChanged += (sender, args) =>
            {
                _lazyCurrentCallCount++;
                _frame.Continue = false;
                _lazyCurrentChanged_Now = DateTime.Now;
            };

        }
        private void DispatcherWait()
        {
            _frame.Continue = true;
            Dispatcher.PushFrame(_frame);
        }
        #endregion

        [Test]
        public void CurrentChangedTest()
        {
            Assert.AreEqual(9, _target.Count);

            DateTime moveCurrentNow;
            TimeSpan dt;

            //////////////////////////////////
            moveCurrentNow = DateTime.Now;
            _target.MoveCurrentToLast();

            Assert.AreEqual(0, _lazyCurrentCallCount);

            DispatcherWait();

            dt = _lazyCurrentChanged_Now - moveCurrentNow;

            Assert.AreEqual(1, _lazyCurrentCallCount);
            Assert.IsTrue(_delay - _delayTolerance < dt.TotalMilliseconds && dt.TotalMilliseconds < _delay + _delayTolerance);

            //////////////////////////////////
            moveCurrentNow = DateTime.Now;
            _target.MoveCurrentTo(5);

            Assert.AreEqual(1, _lazyCurrentCallCount);

            DispatcherWait();

            dt = _lazyCurrentChanged_Now - moveCurrentNow;

            Assert.AreEqual(2, _lazyCurrentCallCount);
            Assert.IsTrue(_delay - _delayTolerance < dt.TotalMilliseconds && dt.TotalMilliseconds < _delay + _delayTolerance);
        }
        [Test]
        public void FastCurrentChangedTest()
        {
            Assert.AreEqual(9, _target.Count);

            DateTime moveCurrentNow;
            TimeSpan dt;

            //////////////////////////////////
            _target.MoveCurrentTo(1);
            _target.MoveCurrentTo(2);
            _target.MoveCurrentTo(3);
            _target.MoveCurrentTo(4);
            moveCurrentNow = DateTime.Now;
            _target.MoveCurrentTo(5);

            Assert.AreEqual(0, _lazyCurrentCallCount);

            DispatcherWait();

            dt = _lazyCurrentChanged_Now - moveCurrentNow;

            Assert.AreEqual(1, _lazyCurrentCallCount);
            Assert.IsTrue(_delay - _delayTolerance < dt.TotalMilliseconds && dt.TotalMilliseconds < _delay + _delayTolerance);
 
            //////////////////////////////////
            _target.MoveCurrentTo(1);
            _target.MoveCurrentTo(2);
            _target.MoveCurrentTo(3);
            _target.MoveCurrentTo(4);
            moveCurrentNow = DateTime.Now;
            _target.MoveCurrentTo(5);

            Assert.AreEqual(1, _lazyCurrentCallCount);

            DispatcherWait();

            dt = _lazyCurrentChanged_Now - moveCurrentNow;

            Assert.AreEqual(2, _lazyCurrentCallCount);
            Assert.IsTrue(_delay - _delayTolerance < dt.TotalMilliseconds && dt.TotalMilliseconds < _delay + _delayTolerance);
 
        }
    }
}
